package com.exposit.zbs.controller;

import com.exposit.zbs.model.*;
import com.exposit.zbs.service.IGrantApplicationService;
import com.exposit.zbs.service.IUserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


/**
 * This controller for Admin features
 */
@Controller
@RequestMapping("/admin")
public class AdminController {

	@Autowired
	private IGrantApplicationService grantAppService;

	@Autowired
	private IUserService userService;

	/**
	 * This method show all view areas and provide oportunities for deleting, creating and updating grant areas
	 *
	 * @param session
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/areas/viewAll", method = RequestMethod.GET)
	public ModelAndView viewAllAreas(HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				List<GrantArea> grantAreas = grantAppService.getAllAreas();
				mav.setViewName("admin.areas.viewAll");
				if (grantAreas != null && grantAreas.size() > 0) {
					mav.addObject("grantAreas", grantAreas);
					mav.addObject("newGrantArea", new GrantArea());
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}

		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	/**
	 * This method for save a created Grant Area
	 *
	 * @param grantArea Composed Grant Ara via spring
	 * @param session
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/areas/viewAll", method = RequestMethod.POST)
	public ModelAndView saveGrantArea(GrantArea grantArea, HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				grantAppService.saveGrantArea(grantArea);
				List<GrantArea> grantAreas = grantAppService.getAllAreas();
				mav.setViewName("admin.areas.viewAll");
				if (grantAreas != null && grantAreas.size() > 0) {
					mav.addObject("grantAreas", grantAreas);
					mav.addObject("newGrantArea", new GrantArea());
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}
		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	/**
	 * This method for remove Grant Area by id
	 *
	 * @param grantAreaId Id of grant area
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/areas/remove/{grantAreaId}", method = RequestMethod.GET)
	public ModelAndView removeGrantArea(@PathVariable String grantAreaId, HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Long grantAreaIdValue = new Long(grantAreaId);
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				grantAppService.removeGrantAreaById(grantAreaIdValue);
				List<GrantArea> grantAreas = grantAppService.getAllAreas();
				mav.setViewName("redirect:/admin/areas/viewAll");
				if (grantAreas != null && grantAreas.size() > 0) {
					mav.addObject("grantAreas", grantAreas);
					mav.addObject("newGrantArea", new GrantArea());
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}
		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	/**
	 * This method is used to display a list of all the users of the site
	 *
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/users/viewAll", method = RequestMethod.GET)
	public ModelAndView viewAllUsers(HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				List<User> users = userService.getAllUsers();
				mav.setViewName("admin.users.viewAll");
				if (users != null && users.size() > 0) {
					mav.addObject("users", users);
					mav.addObject("newUser", new User());
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}
		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	@RequestMapping(value = "/users/viewAll", method = RequestMethod.POST)
	public ModelAndView saveUser(User user, HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				userService.saveUser(user);
				List<User> users = userService.getAllUsers();
				mav.setViewName("admin.users.viewAll");
				if (users != null && users.size() > 0) {
					mav.addObject("users", users);
					mav.addObject("newUser", new User());
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}
		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	@RequestMapping(value = "/grants/viewAll", method = RequestMethod.GET)
	public ModelAndView viewAllGrants(HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				List<GrantApplication> grantApplications = grantAppService.getApplicationsForAdminReview();
				mav.setViewName("admin.grants.viewAll");
				if (grantApplications != null && grantApplications.size() > 0) {
					mav.addObject("grantApplications", grantApplications);
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}
		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	@RequestMapping(value = "/grants/viewAll", method = RequestMethod.POST)
	public ModelAndView saveGrantApplication(GrantApplication grantApplication, HttpSession session) {

		ModelAndView mav = new ModelAndView();
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
				grantAppService.saveGrant(grantApplication);
				List<GrantApplication> grantApplications = grantAppService.getAllGrants();
				mav.setViewName("admin.grants.viewAll");
				if (grantApplications != null && grantApplications.size() > 0) {
					mav.addObject("grantApplications", grantApplications);
					mav.addObject("newGrantApplicationa", new GrantApplication());
				} else {
					mav.addObject("message", "Nothing to view");
				}
				return mav;
			}
		}
		mav = new ModelAndView("redirect:/");
		return mav;
	}

	@RequestMapping(value = "/sendMoney", method = RequestMethod.POST)
	public ModelAndView saveMoney(Long moneyAmount, Long grantId, HttpSession session) {

		ModelAndView mav = new ModelAndView("redirect:/grant/view/" + grantId.toString());
		GrantApplication grantApplication = grantAppService.getGrantById(grantId);
		if (grantApplication != null) {
			Object currentUserObject = session.getAttribute("sessionUser");
			if (currentUserObject != null && currentUserObject instanceof User) {
				User currentUser = (User) currentUserObject;
				if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
					BigDecimal limit = grantAppService.getAvailMoneyForArea(grantApplication.getGrantArea().getGrantAreaId());
					if (moneyAmount <= limit.longValue()) {
						MoneyTransferFromFund mtff = new MoneyTransferFromFund();
						mtff.setDate(new Date());
						mtff.setGrantApplication(grantApplication);
						mtff.setMoneyAmount(moneyAmount);
						grantAppService.saveMoneyTransferFromFund(mtff);
					} else {
						mav.addObject("error", "You should request to transfer very big sum!");
					}
				}
			}
		}

		return mav;
	}

	@RequestMapping(value = "/report", method = RequestMethod.GET)
	public ModelAndView viewReport() {

		ModelAndView mav = new ModelAndView("admin.report");
		List<DateValueGraphicEntry> chartData = grantAppService.getMoneyReporyGraphic();
		mav.addObject("finishedList", grantAppService.getFinishedGrantApplications());
		mav.addObject("moneyTrasferGrData", chartData);
		return mav;
	}
	
	@RequestMapping(value = "/users/edit/{userId}", method = RequestMethod.GET)
	public ModelAndView editUser(HttpSession session, @PathVariable Long userId, @PathVariable("userId") User user) {

		ModelAndView mav = new ModelAndView("profile.edit");
		mav.addObject("user", user);
		return mav;
	}

	@RequestMapping(value = "/users/edit/{userId}", method = RequestMethod.POST)
	public ModelAndView editUser(@PathVariable Long userId, @PathVariable("userId") final User originalUser, User user, HttpSession session) {

		ModelAndView mav = new ModelAndView("profile.edit");
		Object currentUserObject = session.getAttribute("sessionUser");
		if (currentUserObject != null && currentUserObject instanceof User) {
			User currentUser = (User) currentUserObject;
			if (currentUser.getRole().getRoleName().equals("ROLE_ADMIN")) {
			user.setUserId(originalUser.getUserId());
			user.setRole(originalUser.getRole());
			userService.updateUserData(user);
			mav.addObject("user", user);
			mav.setViewName("redirect:/admin/users/viewAll");
			}
		} else {
			return new ModelAndView("redirect:/");
		}
		return mav;
	}
}
